// Generated on Mon Aug 10 2015 12:22:54 GMT+0800 (中国标准时间) using generator-ngstone 0.2.8
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'
var path = require('path');

module.exports = function (grunt) {

    // Load grunt tasks automatically
    require('load-grunt-tasks')(grunt);

    // Time how long tasks take. Can help when optimizing build times
    require('time-grunt')(grunt);

    // Configurable paths for the application
    var appConfig = {
        projectName: require('./bower.json').name,//added by stone
        app: 'public/javascripts/app',
        dist: 'node_static/dist'
    };

    // Define the configuration for all the tasks
    grunt.initConfig({

        // Project settings
        yeoman: appConfig,
        connect: {
            options: {
                port: 9000,
                // Change this to '0.0.0.0' to access the server from outside.
                hostname: 'localhost',
                livereload: 35729
            },
            livereload: {
                options: {
                    open: true,
                    middleware: function (connect) {
                        return [
//                            connect.static('.tmp'),
//                            connect().use(
//                                '/node_static/javascripts/app/',
//                                connect.static('')
//                            ),
                            connect.static(appConfig.app),
                            function mockMiddleware(req, res, next) {//用于mock数据
                                grunt.log.writeln('request from client:' + req.url);
                                var urlReg = /^\/(.+)\.json\?_method=(GET|POST|PATCH|DELETE|PUT).*$/;// /users/5.json?_method=GET
                                var match = req.url.match(urlReg);// ['...','users/5','GET']
                                if(!match){
                                    grunt.log.writeln('not matched,passed...');
                                    return next();
                                }
                                var fileNameSegments = [];
                                var segments = match[1].split('/');
                                segments.forEach(function (pathName) {
                                    if(/\D+/.test(pathName)){//非数字
                                        fileNameSegments.push(pathName)
                                    }else if(/\d+/.test(pathName)){//数字
                                        fileNameSegments.push('N')
                                    }
                                });
                                var fileName = fileNameSegments.join('.');// user.N
                                fileName += '#' + match[2].toUpperCase() + '.json';// user.N#GET.json
                                grunt.log.writeln('parsed fileName:' + fileName);
                                var filePath = path.join('mock',segments[0],fileName);
                                grunt.log.writeln('parsed filePath:' + filePath);
                                var result = '';
                                if(grunt.file.exists(filePath)){
                                    result = grunt.file.read(filePath);
                                }else{
                                    result = JSON.stringify({
                                        stat:'ERROR',
                                        errors:'mock data file:【' + filePath + '】 does not exist!'
                                    })
                                }
                                grunt.log.writeln(result);
                                res.end(result);
                            }
                        ];
                    }
                }
            },
            test: {
                options: {
                    port: 9001,
                    middleware: function (connect) {
                        return [
                            connect.static('test'),
                            connect.static(appConfig.app)
                        ];
                    }
                }
            },
            dist: {
                options: {
                    open: true,
                    base: '<%= yeoman.dist %>'
                }
            }
        },
        watch: {
            gruntfile: {
                files: ['Gruntfile.js']
            },
            livereload: {
                options: {
                    livereload: '<%= connect.options.livereload %>'
                },
                files: [
                    '<%= yeoman.app %>/view/**/*.html',
                    '<%= yeoman.app %>/**/*.js',
                    '/stylesheets/**/*.css',
                    '/images/**/*.*'
                ]
            }
        },
        //清除文件
        clean: {
            dist: {
                files: [
                    {
                        dot: true,
                        src: [
                            '.tmp',
                            'views/dist',
                            'node_static'
                        ]
                    }
                ]
            },
            server: '.tmp'
        },

        //打包模板
        ngtemplates: {
            dist: {
                src: [
                    'node_static/javascripts/app/view/**/*.html'//这里的./很重要，必须和指令里的templateUrl等一致，否则应用运行时，模板无法加载
                ],
                dest: 'node_static/scripts/ngtemplates.js',
                options: {
                    module: 'fscApp',
                    prefix: '/',
                    htmlmin: {
                        collapseBooleanAttributes: true,
                        collapseWhitespace: true,
                        removeAttributeQuotes: false,//必须为false，否则usemin的正则无法匹配
                        removeComments: true, // Only if you don't use comment directives!
                        removeEmptyAttributes: true,
                        removeRedundantAttributes: false, //removing this as it can removes properties that can be used when styling
                        removeScriptTypeAttributes: true,
                        removeStyleLinkTypeAttributes: true
                    }
                }
            }
        },
        jadeUsemin: {
            main: {
                options: {
                    tasks: { //optional if you want to use defaults
                        js: ['concat', 'uglify'],
                        css: [ 'cssmin']
                    },
                    prefix: '', //optional - add prefix to the path [default='']
                    deprefix_dest: '', //optional - add prefix to the path [default='']
                },
                files: [{
                    src: ['views/layout.jade']
                },{
                    src: ['views/layout.jade'],
                    dest: 'views/dist/layout.jade'
                }]
            }
        },

        // Make sure code styles are up to par and there are no obvious mistakes
        jshint: {
            options: {
                jshintrc: '.jshintrc',
                reporter: require('jshint-stylish')
            },
            all: {
                src: [
                    'Gruntfile.js',
                    '<%= yeoman.app %>/javascripts/app/**/*.js'
                ]
            },
            test: {
                options: {
                    jshintrc: 'test/.jshintrc'
                },
                src: ['test/spec/{,*/}*.js']
            }
        },

        // Renames files for browser caching purposes
        filerev: {
            dist: {
                src: [
                    '<%= yeoman.dist %>/app/{,*/}*.js',
                    '<%= yeoman.dist %>/stylesheets/{,*/}*.css'
                ]
            }
        },

        // Performs rewrites based on filerev and the useminPrepare configuration
        jadeFilerevUsemin: {
            main: {
                options: {
                    prefix: 'node_static/dist', //optional - add prefix to the path [default='']
                    deprefix_dest: '/node_static/dist', //optional - add prefix to the path [default='']
                },
                src: 'views/layout.jade',
                dest: 'views/dist/layout.jade',
            }
        },


        // ng-annotate tries to make the code safe for minification automatically
        // by using the Angular long form for dependency injection.
        ngAnnotate: {
            app: {
                files: [
                    {
                        expand: true,
                        cwd: '<%= yeoman.app %>',
                        src: ['**/*.js'],
                        dest: 'node_static/javascripts/app'
                    }
                ]
            }
        },

        concat: {//后期添加，将打包好了模板js，合并到之前的js里，由于useminPrepare通过读取index.html的注释生成concat的列表，无法将此模板文件打包进去，所以只能二次合并
            ngtemplates: {
                src: ['node_static/dist/app/app.min.js', 'node_static/scripts/ngtemplates.js'],
                dest: 'node_static/dist/app/app.min.js'
            }
        },
        // Copies remaining files to places other tasks can use
        copy: {
            html:{
                files: [
                    {
                        expand: true,
                        cwd: 'public',
                        src: 'javascripts/app/view/**/*.html',
                        dest: 'node_static/'
                    },
                ]
            },
            dist: {
                files: [
                    {
                        expand: true,
                        dot: true,
                        cwd: 'public',
                        dest: '<%= yeoman.dist %>',
                        src: [
                            '*.{ico,png,txt}',
                            '*.html',
                            'images/**/*.*',//modified by stone //imagesmin注释掉后，images目录不复制了
                            'fonts/*'
                        ]
                    },
                    {
                        expand: true,
                        dot: true,
                        cwd: 'public',
                        dest: 'node_static/',
                        src: [
                            'stylesheets/**/*.*'
                        ]
                    },
                    {
                        expand: true,
                        dot: true,
                        cwd: 'public/javascripts',
                        dest: 'node_static/javascripts/',
                        src: [
                            'thd/**/*.*'
                        ]
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/bootstrap/dist',
                        src: 'fonts/*',
                        dest: '<%= yeoman.dist %>'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/fontawesome',
                        src: 'fonts/*',
                        dest: '<%= yeoman.dist %>'
                    },
                    {
                        expand: true,
                        dot: true,
                        cwd: 'views',
                        dest: 'views/dist',
                        src: [
                            '*.jade'
                        ]
                    }
                    //more copies
                ]
            }
        }
    });

    grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
        if (target === 'build') {
            return grunt.task.run(['build', 'connect:dist:keepalive']);
        }
        if (target === 'dist') {
            return grunt.task.run(['connect:dist:keepalive']);
        }

        grunt.task.run([
            'clean:server',
//            'concurrent:server',
            'connect:livereload',
            'watch'
        ]);
    });

    grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
        grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
        grunt.task.run(['serve:' + target]);
    });

    grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
        grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
        grunt.task.run(['serve:' + target]);
    });

    grunt.registerTask('build', [
        'clean:dist',//清除目录
        'copy:html',
        'ngtemplates',
        'ngAnnotate:app',
        'copy:dist',
        'jadeUsemin',
        'concat:ngtemplates',
        'filerev',
        'jadeFilerevUsemin'
    ]);
    grunt.registerTask('default', ['build']);
};
